import { DatasetRunsTable } from "@/src/features/datasets/components/DatasetRunsTable"; import { api } from "@/src/utils/api"; import { useRouter } from "next/router"; import Link from "next/link"; import { DetailPageNav } from "@/src/features/navigate-detail-pages/DetailPageNav"; import { DatasetActionButton } from "@/src/features/datasets/components/DatasetActionButton"; import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger, } from "@/src/components/ui/dropdown-menu"; import { DeleteDatasetButton } from "@/src/components/deleteButton"; import { DuplicateDatasetButton } from "@/src/features/datasets/components/DuplicateDatasetButton"; import { useState, useCallback } from "react"; import { Bot, FlaskConical, MoreVertical } from "lucide-react"; import { useHasProjectAccess } from "@/src/features/rbac/utils/checkProjectAccess"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, } from "@/src/components/ui/dialog"; import { Button } from "@/src/components/ui/button"; import { CreateExperimentsForm } from "@/src/features/experiments/components/CreateExperimentsForm"; import { showSuccessToast } from "@/src/features/notifications/showSuccessToast"; import { DropdownMenuItem } from "@/src/components/ui/dropdown-menu"; import { DatasetAnalytics } from "@/src/features/datasets/components/DatasetAnalytics"; import { RESOURCE_METRICS } from "@/src/features/dashboard/lib/score-analytics-utils"; import { usePostHogClientCapture } from "@/src/features/posthog-analytics/usePostHogClientCapture"; import Page from "@/src/components/layouts/page"; import { getDatasetTabs, DATASET_TABS, } from "@/src/features/navigation/utils/dataset-tabs"; import { TemplateSelector } from "@/src/features/evals/components/template-selector"; import { useEvaluatorDefaults } from "@/src/features/experiments/hooks/useEvaluatorDefaults"; import { useExperimentEvaluatorData } from "@/src/features/experiments/hooks/useExperimentEvaluatorData"; import { EvaluatorForm } from "@/src/features/evals/components/evaluator-form"; import useLocalStorage from "@/src/components/useLocalStorage"; import { createBreadcrumbItems } from "@/src/features/folders/utils"; export default function Dataset() { const router = useRouter(); const capture = usePostHogClientCapture(); const projectId = router.query.projectId as string; const datasetId = router.query.datasetId as string; const utils = api.useUtils(); const [isCreateExperimentDialogOpen, setIsCreateExperimentDialogOpen] = useState(false); const [selectedMetrics, setSelectedMetrics] = useLocalStorage( `${projectId}-dataset-chart-metrics`, RESOURCE_METRICS.map((metric) => metric.key), ); const [scoreOptions, setScoreOptions] = useState< { key: string; value: string; }[] >([]); const dataset = api.datasets.byId.useQuery({ datasetId, projectId, }); const hasReadAccess = useHasProjectAccess({ projectId, scope: "evalJobExecution:read", }); const hasExperimentWriteAccess = useHasProjectAccess({ projectId, scope: "promptExperiments:CUD", }); const handleExperimentSuccess = async (data?: { success: boolean; datasetId: string; runId: string; runName: string; }) => { setIsCreateExperimentDialogOpen(false); if (!data) return; void utils.datasets.runsByDatasetId.invalidate(); void utils.datasets.baseRunDataByDatasetId.invalidate(); showSuccessToast({ title: "Experiment triggered successfully", description: "Waiting for experiment to complete...", link: { text: "View experiment", href: `/project/${projectId}/datasets/${data.datasetId}/compare?runs=${data.runId}`, }, }); }; const hasEvalReadAccess = useHasProjectAccess({ projectId, scope: "evalJob:read", }); const hasEvalWriteAccess = useHasProjectAccess({ projectId, scope: "evalJob:CUD", }); const evalTemplates = api.evals.allTemplates.useQuery({ projectId, }); const evaluators = api.evals.jobConfigsByTarget.useQuery( { projectId, targetObject: "dataset" }, { enabled: hasEvalReadAccess && !!datasetId, }, ); const { createDefaultEvaluator } = useEvaluatorDefaults(); const { activeEvaluators, pausedEvaluators, selectedEvaluatorData, showEvaluatorForm, handleConfigureEvaluator, handleCloseEvaluatorForm, handleEvaluatorSuccess, handleSelectEvaluator, } = useExperimentEvaluatorData({ datasetId, createDefaultEvaluator, evaluatorsData: evaluators.data, evalTemplatesData: evalTemplates.data, refetchEvaluators: evaluators.refetch, }); // This function will be passed to the EvaluatorForm to modify form values before submission const preprocessFormValues = useCallback((values: any) => { // Ask the user if they want to run on historic data const shouldRunOnHistoric = confirm( "Do you also want to execute this evaluator on historic data? If not, click cancel.", ); // If the user confirms, include EXISTING in the timeScope if (shouldRunOnHistoric && !values.timeScope.includes("EXISTING")) { values.timeScope = [...values.timeScope, "EXISTING"]; } return values; }, []); const datasetName = dataset.data?.name ?? ""; const segments = datasetName.split("/").filter((s) => s.trim()); const folderPath = segments.length > 1 ? segments.slice(0, -1).join("/") : ""; const breadcrumbItems = folderPath ? createBreadcrumbItems(folderPath) : []; return ( ({ name: item.name, href: `/project/${projectId}/datasets?folder=${encodeURIComponent(item.folderPath)}`, })), ], help: dataset.data?.description ? { description: dataset.data.description, } : undefined, tabsProps: { tabs: getDatasetTabs(projectId, datasetId), activeTab: DATASET_TABS.RUNS, }, actionButtonsRight: ( <> {hasEvalReadAccess && (
)} `/project/${projectId}/datasets/${entry.id}`} listKey="datasets" /> { event.preventDefault(); return false; }} > {hasReadAccess && ( Manage Evaluators )} ), }} > {/* Dialog for configuring evaluators */} {selectedEvaluatorData && ( { if (!open) { handleCloseEvaluatorForm(); } }} > {selectedEvaluatorData.evaluator.id ? "Edit" : "Configure"}{" "} Evaluator )}
); }